<template>
  <div class="index" ref="index">
    <div class="title" v-show="!isShow">
      <div class="cloud1"></div>
      <div class="cloud2"></div>
    </div>
    <div id="stage" ref="main" class="main" v-show="isShow">
      <div
          class="choice"
          v-show="peopleNum - 1 === index"
          v-for="(item, index) in clothings"
          :key="index"
      >
        <div
            class="li"
            v-for="(data, index) in item.imgs"
            :key="index"
            @click="handleClick(index, item.name)"
            :style="{ backgroundImage: 'url(' + data + ')' }"
        ></div>
      </div>
      <div ref="card" class="footer">
        <div class="generate" @click="makeGenerate()"></div>
        <div class="tab">
          <div
              class="tabs"
              v-for="(item, index) in tpl"
              :class="cardIndex === index ? 'activeClass' : ''"
              :key="index"
              :style="{ backgroundImage: 'url(' + item.icon + ')' }"
              @click="handleClickTab(index)"
          ></div>
          <div class="arrow" :class="isCardHidden ? 'tabClass' : ''" @click="handleClickHidden"></div>
        </div>

        <div class="cards" v-show="!isCardHidden">
          <div
              class="imgs"
              :class="cardIndex === 0 ? 'radius' : ''"
              v-for="(item, index) in tpl[cardIndex].imgs"
              :key="index"
              :style="{ backgroundImage: 'url(' + item + ')' }"
              @click="handleChangeBg(index, tpl[cardIndex].className)"
          ></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import gsap from 'gsap'
import * as PIXI from 'pixi.js'
import { tpl, clothings } from '@/config/tpl'
export default {
  name: 'Index',
  data () {
    return {
      tpl,
      clothings,
      isShow: false,
      isCloud: false,
      isCardHidden: false,
      peopleNum: null,
      decNum: null,
      petNum: null,
      cardIndex: 0,
      app: null,
      loader: null,
      sprite: null,
      resources: null,
      dec: null,
      space: 10,
      squ: 0,
      manContainer: null,
      womanContainer: null,
      flag: true, // 是否选中
      startPosX: 0, // 开始移动时X的位置
      startPosY: 0, // 开始移动时Y的位置
      parentPosX: 0,
      parentPosY: 0,
      parentName: null,
      resizePosX: 0,
      resizeParentName: null
    }
  },
  methods: {
    // 选项卡切换
    handleClickTab (index) {
      this.isCardHidden = false
      this.cardIndex = index
      this.clearSelected()
      if (index !== 1) {
        this.peopleNum = 0
      }
    },
    // 是否影藏选项卡
    handleClickHidden () {
      this.isCardHidden = !this.isCardHidden
    },
    // 初始化
    init () {
      this.app = new PIXI.Application({
        width: 256,
        height: 256,
        autoDensity: true,
        transparent: true,
        resolution: 1
      })
      this.loader = new PIXI.Loader()
      this.loadTextureAll()
      this.sprite = PIXI.Sprite
      this.app.renderer.view.style.position = 'absolute'
      this.app.renderer.view.style.display = 'block'
      this.app.renderer.autoResize = true
      this.app.renderer.resize(this.$refs.index.offsetWidth, this.$refs.index.offsetHeight)
      this.$refs.main.appendChild(this.app.view)
    },
    // 加载所有图片纹理
    loadTextureAll () {
      this.loader
        .add('dec', 'json/dec.json')
        .add('dress', 'json/dress.json')
        .add('manHair', 'json/manHair.json')
        .add('others', 'json/other.json')
        .add('pets', 'json/pets.json')
        .add('team', 'json/team.json')
        .add('wedding', 'json/wedding.json')
        .add('womanHair', 'json/womanHair.json')
        .add('img/bg1.jpg')
        .add('img/bg2.jpg')
        .add('img/bg3.jpg')
        .add('img/bg4.jpg')
        .add('img/bg5.jpg')
        .add('img/bg6.jpg')
        .add('img/bg7.jpg')
        .add('img/bg8.jpg')
        .add('img/bg9.jpg')
        .load((loader, resources) => {
          this.resources = resources
        })
        .onComplete.add(() => {
          this.bgSpr()
        })
    },
    // 添加背景图片
    bgSpr () {
      const bgContainer = new PIXI.Container()
      bgContainer.name = 'bgContainer'
      // const bgSpr = this.sprite.from(this.resources.bgs.textures['bg1.jpg'])
      const bgSpr = this.sprite.from(this.loader.resources['img/bg1.jpg'].texture)
      bgSpr.position.set(0, 0)
      bgSpr.name = 'bg'
      bgSpr.interactive = true
      bgSpr.autoResize = true
      bgSpr.width = this.$refs.index.offsetWidth
      bgSpr.height = this.$refs.index.offsetHeight
      bgSpr.interactive = true
      bgSpr.on('tap', () => {
        this.clearSelected()
        this.peopleNum = 0
      })
      bgContainer.addChild(bgSpr)
      this.app.stage.addChild(bgContainer)
    },
    // 添加人物
    loadTextureMan (index) {
      if (index === 0 && this.manContainer === null) {
        const male = [340 / 2, 681 / 2]
        const maleSpace = [male[0] + this.space, male[1] + this.space]
        const clothes = this.sprite.from(this.resources.dress.textures['bg-clothes1.png'])
        clothes.scale.set(0.5, 0.5)
        clothes.position.set(0, 148 / 2)
        const face = this.sprite.from(this.resources.others.textures['bridegroom-face.png'])
        face.scale.set(0.5, 0.5)
        face.position.set(135 / 2, 1)
        const hair = this.sprite.from(this.resources.manHair.textures['bg-hair1.png'])
        hair.scale.set(0.5, 0.5)
        hair.position.set(137 / 2, 0)
        const manContainer = this.manContainer = new PIXI.Container()
        manContainer.name = 'manContainer'
        manContainer.addChild(clothes, face, hair)
        this.addSpr(manContainer, maleSpace)
      } else if (index === 1 && this.womanContainer === null) {
        const female = [460 / 2, 806 / 2]
        const femaleSpace = [female[0] + this.space, female[1] + this.space]
        const feclothes = this.sprite.from(this.resources.wedding.textures['b-clothes1.png'])
        feclothes.scale.set(0.5, 0.5)
        feclothes.position.set(0, 200 / 2)
        const feface = this.sprite.from(this.resources.others.textures['bride-face.png'])
        feface.scale.set(0.5, 0.5)
        feface.position.set(140 / 2, 60 / 2)
        const fehair = this.sprite.from(this.resources.womanHair.textures['b-hair1.png'])
        fehair.scale.set(0.5, 0.5)
        fehair.position.set(60 / 2, 0)
        const womanContainer = this.womanContainer = new PIXI.Container()
        womanContainer.name = 'womanContainer'
        womanContainer.addChild(feclothes, feface, fehair)
        this.addSpr(womanContainer, femaleSpace)
      }
    },
    // 添加装饰
    loadTextureDec () {
      let w = 0
      let h = 0
      for (const k in this.resources.dec.data.frames) {
        if (k === 'dec' + this.decNum) {
          w = this.resources.dec.data.frames[k].sourceSize.w
          h = this.resources.dec.data.frames[k].sourceSize.h
        }
      }
      const de = [w / 2, h / 2]
      const decSpace = [de[0] + this.space, de[1] + this.space]
      const dec = this.sprite.from(this.resources.dec.textures['dec' + this.decNum])
      dec.name = 'dec' + this.decNum
      dec.scale.set(0.5, 0.5)
      this.addSpr(dec, decSpace)
    },
    // 添加宠物
    loadTexturePet () {
      let w = 0
      let h = 0
      for (const k in this.resources.pets.data.frames) {
        if (k === 'pet' + this.petNum) {
          w = this.resources.pets.data.frames[k].sourceSize.w
          h = this.resources.pets.data.frames[k].sourceSize.h
        }
      }
      const pe = [w / 2, h / 2]
      const petSpace = [pe[0] + this.space, pe[1] + this.space]
      const pet = this.sprite.from(this.resources.pets.textures['pet' + this.petNum])
      pet.name = 'pet' + this.petNum
      pet.scale.set(0.5, 0.5)
      this.addSpr(pet, petSpace)
    },
    // 添加处理
    addSpr (who, maleSpace) {
      const container = new PIXI.Container()
      if (who.name === 'womanContainer') {
        container.name = 'womanSprite'
      } else if (who.name === 'manContainer') {
        container.name = 'manSprite'
      } else {
        container.name = 'sprite' + this.squ
        this.squ++
      }
      this.clearSelected()
      // 出现的位置
      const capos = this.randomPos()
      container.width = maleSpace[0]
      container.height = maleSpace[1]
      container.pivot.set(maleSpace[0] / 2, maleSpace[1] / 2)
      container.position.set(capos.x, capos.y)

      // 添加边框
      const graphics = new PIXI.Graphics()
      graphics.name = 'borderLiner'
      graphics.lineStyle(1, 0xaaaaaa)
      graphics.drawRoundedRect(0, 0, maleSpace[0], maleSpace[1], 5)
      graphics.position.set(0, 0)

      // 缩放按钮
      const resizeBtn = this.sprite.from(this.resources.others.textures['btn-resize.png'])
      resizeBtn.name = 'resizeBtn'
      resizeBtn.scale.set(0.5, 0.5)
      resizeBtn.position.set(maleSpace[0] - resizeBtn.width / 2, -resizeBtn.height / 2)
      resizeBtn.interactive = true

      // 删除按钮
      const delBtn = this.sprite.from(this.resources.others.textures['btn-del.png'])
      delBtn.name = 'delBtn'
      delBtn.scale.set(0.5, 0.5)
      delBtn.position.set(-delBtn.width / 2, maleSpace[1] - delBtn.height / 2)
      delBtn.interactive = true

      who.position.set(this.space / 2, this.space / 2)
      who.interactive = true

      container.addChild(graphics, resizeBtn, delBtn, who)
      // 添加至舞台
      this.app.stage.addChild(container)

      // 绑定精灵的事件
      who.on('touchstart', this.dropStart)
        .on('touchmove', this.dropMove)
        .on('touchend', this.dropEnd)
      // 缩放按钮的事件
      resizeBtn.on('touchstart', this.resizeStart)
      // 绑定删除按钮精灵的事件
      delBtn.on('touchend', this.delClick)
    },
    // 处理点击的是哪一个
    handleChangeBg (index, name) {
      // 改变背景
      if (name === 'place') {
        const bgNum = index + 1
        // this.app.stage.getChildByName('bgContainer').children[0].texture = this.resources.bgs.textures['bg' + bgNum + '.jpg']
        this.app.stage.getChildByName('bgContainer').children[0].texture = this.loader.resources['img/bg' + bgNum + '.jpg'].texture
      }
      // 添加人物
      if (name === 'human') {
        this.peopleNum = index + 1
        this.loadTextureMan(index)
      }
      // 添加装饰物
      if (name === 'dec') {
        this.decNum = index + 1
        this.loadTextureDec()
      }
      // 添加宠物
      if (name === 'pet') {
        this.petNum = index + 1
        this.loadTexturePet()
      }
    },
    // 点击换衣服和头发
    handleClick (index, name) {
      switch (name) {
        case 'bridegroom': {
          if (index <= 5) {
            const manHair = index + 1
            this.app.stage.getChildByName('manSprite').children[3].children[2].texture = this.resources.manHair.textures['bg-hair' + manHair + '.png']
          } else {
            const manClothes = index - 5
            this.app.stage.getChildByName('manSprite').children[3].children[0].texture = this.resources.dress.textures['bg-clothes' + manClothes + '.png']
          }
          break
        }
        case 'bride': {
          if (index <= 5) {
            const womanHair = index + 1
            this.app.stage.getChildByName('womanSprite').children[3].children[2].texture = this.resources.womanHair.textures['b-hair' + womanHair + '.png']
          } else {
            const womanClothes = index - 5
            this.app.stage.getChildByName('womanSprite').children[3].children[0].texture = this.resources.wedding.textures['b-clothes' + womanClothes + '.png']
          }
          break
        }
        case 'catamite': {
          const ca = [240 / 2, 600 / 2]
          const caSpace = [ca[0] + this.space, ca[1] + this.space]
          const catamite = this.sprite.from(this.resources.team.textures['cm' + (index + 1) + '.png'])
          catamite.scale.set(0.5, 0.5)
          this.addSpr(catamite, caSpace)
          break
        }
        case 'groomsman': {
          const gr = [240 / 2, 650 / 2]
          const grSpace = [gr[0] + this.space, gr[1] + this.space]
          const groomsman = this.sprite.from(this.resources.team.textures['bmm' + (index + 1) + '.png'])
          groomsman.scale.set(0.5, 0.5)
          this.addSpr(groomsman, grSpace)
          break
        }
        case 'bridesmaid': {
          const br = [300 / 2, 650 / 2]
          const brSpace = [br[0] + this.space, br[1] + this.space]
          const bridesmaid = this.sprite.from(this.resources.team.textures['bm' + (index + 1) + '.png'])
          bridesmaid.scale.set(0.5, 0.5)
          this.addSpr(bridesmaid, brSpace)
          break
        }
        case 'girl': {
          const gi = [320 / 2, 530 / 2]
          const giSpace = [gi[0] + this.space, gi[1] + this.space]
          const girl = this.sprite.from(this.resources.team.textures['cf' + (index + 1) + '.png'])
          girl.scale.set(0.5, 0.5)
          this.addSpr(girl, giSpace)
          break
        }
      }
    },
    // 清除选中
    clearSelected () {
      // 从1开始循环，因为0代表的是背景图片
      for (let i = 1; i < this.app.stage.children.length; i++) {
        this.app.stage.children[i].children[0].visible = false
        this.app.stage.children[i].children[1].visible = false
        this.app.stage.children[i].children[2].visible = false
      }
    },
    // 随机位置
    randomPos () {
      return {
        x: this.$refs.index.offsetWidth / 2 + Math.random() * 40,
        y: this.$refs.index.offsetHeight / 2 + Math.random() * 40
      }
    },
    // 开始移动
    dropStart (el) {
      this.clearSelected()
      el.currentTarget.parent.children[0].visible = true
      el.currentTarget.parent.children[1].visible = true
      el.currentTarget.parent.children[2].visible = true
      if (el.currentTarget.name === 'manContainer') {
        this.peopleNum = 1
      } else if (el.currentTarget.name === 'womanContainer') {
        this.peopleNum = 2
      } else {
        this.peopleNum = 0
      }
      // 设置层级调整，添加进入的顺序
      this.app.stage.setChildIndex(el.currentTarget.parent, this.app.stage.children.length - 1)
      if (this.flag && el.currentTarget.name !== 'resizeBtn') {
        this.flag = false
        this.startPosX = el.data.global.x
        this.startPosY = el.data.global.y
        this.parentPosX = el.currentTarget.parent.getGlobalPosition().x
        this.parentPosY = el.currentTarget.parent.getGlobalPosition().y
        this.parentName = el.currentTarget.parent.name
      }
    },
    // 移动中
    dropMove (el) {
      if (el.currentTarget.name !== 'resizeBtn' && this.parentName === el.currentTarget.parent.name) {
        const tempX = el.data.global.x
        const tempY = el.data.global.y
        el.currentTarget.parent.position.set(this.parentPosX + (tempX - this.startPosX), this.parentPosY + (tempY - this.startPosY))
      }
    },
    // 移动结束
    dropEnd () {
      this.flag = true
      this.parentName = ''
      this.resizeParentName = ''

      this.app.stage.getChildByName('bgContainer').off('touchmove', this.resizeMove)
      this.app.stage.getChildByName('bgContainer').interactive = false
    },
    // 开始缩放
    resizeStart (el) {
      if (this.flag) {
        this.resizePosX = el.data.global.x
        this.resizeParentName = el.currentTarget.parent.name

        this.app.stage.getChildByName('bgContainer').interactive = true
        this.app.stage.getChildByName('bgContainer')
          .on('touchmove', this.resizeMove)
          .on('touchend', this.dropEnd)
      }
    },
    // 缩放中
    resizeMove (el) {
      if (el.currentTarget.name === 'bgContainer') {
        const resX = el.data.global.x - this.resizePosX
        this.resizePosX = el.data.global.x
        const scaleNum = this.app.stage.getChildByName(this.resizeParentName).scale.x
        if (resX > 0 && scaleNum <= 1.5) {
          this.app.stage.getChildByName(this.resizeParentName).scale.set(scaleNum + 0.01, scaleNum + 0.01)
        }
        if (resX < 0 && scaleNum >= 0.4) {
          this.app.stage.getChildByName(this.resizeParentName).scale.set(scaleNum - 0.01, scaleNum - 0.01)
        }
      }
    },
    // 删除
    delClick (el) {
      this.app.stage.removeChild(el.currentTarget.parent)
    },
    // 制作海报
    makeGenerate () {
      this.clearSelected()
      this.peopleNum = 0

      this.app.render()
      const imgUrl = this.app.view.toDataURL('image/png')
      // const aaa = this.app.renderer.plugins.extract.image(this.app.stage) // 导出base64的图片
      setTimeout(() => {
        this.$router.push({
          name: 'poster',
          params: {
            imgUrl
          }
        })
      }, 200)
    }
  },
  mounted () {
    gsap.fromTo('.cloud1', 1, { opacity: 0 }, { opacity: 1, delay: 1 })
    gsap.fromTo('.cloud2', 3, { opacity: 0 }, {
      opacity: 1,
      delay: 3,
      onComplete: () => {
        this.isShow = true
      }
    })
    this.init()
  }
}
</script>

<style lang="less" scoped>
@import "./../assets/less/index";
</style>
